#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5+5,M=1e6+5;
struct Car{
    int d,v,a;
}car[N];
struct Frac{
    ll a,b;
    void set(ll x,ll y){
        a=x/__gcd(x,y);
        b=y/__gcd(x,y);
        if (b<0)a*=-1,b*=-1;
    }
    double toDouble(){
        return (double)b*1.0/a;
    }
    Frac operator *(const Frac &u)const{
        Frac res;
        res.set(a*u.a,b*u.b);
        return res;
    }
    bool operator <(const Frac &u)const{
        ll aa=a*u.b,cc=u.a*b;
        return aa<cc;
    }
    bool operator >(const Frac &u)const{
        ll aa=a*u.b,cc=u.a*b;
        return aa>cc;
    }
    bool operator ==(const Frac &u)const{
        ll aa=a*u.b,cc=u.a*b;
        return aa==cc;
    }
    Frac operator +(const Frac &u)const{
        ll aa=a*u.b+u.a*b,bb=b*u.b;
        Frac res;
        res.set(aa,bb);
        return res;
    }
};
vector<int>p;
int cnt[M];
bitset<M>vis;
/*int find(Frac frac,int n){
    int l=1,r=n;
    while(l<r){
        int mid=(l+r)>>1;
        if (r-l==1&&p[l]<frac&&frac<p[r])return l;
        if (p[mid]>frac){
            r=mid;
        }if (p[mid]==frac){
            return mid;
        }else l=mid+1;
    }
    return l;
}*/
int find(double target,int n){
    return lower_bound(p.begin(),p.end(),target)-p.begin();
}
ll sldiv(ll a,ll b){
    if (a%b)return a/b-1;
    else return a/b;
}
void solve(){
    memset(car,0,sizeof(car));
    memset(cnt,0,sizeof(cnt));
    p.clear();
    vis.reset();
    int n,m,l,vmax,osn=0,rmv=0;
    cin>>n>>m>>l>>vmax;
    for (int i=1;i<=n;i++){
        int d,v,a;
        cin>>d>>v>>a;
        car[i]={d,v,a};
    }
    for (int i=1;i<=m;i++){
        int x;
        cin>>x;
        p.push_back(x);
        vis[x]=1;
    }
    p.push_back((int)1e9);
    for (int i=1;i<=n;i++){
        ll d=car[i].d,v=car[i].v,a=car[i].a;
        if (a==0){
            if (v>vmax){
                int pos=find(v,n);
                if (vis[pos])cnt[p[pos]]++;
            }
        }else if (a<0){
            if (v<=vmax)continue;
            Frac t;
            t.set(v-vmax,-a);
            Frac v0,aa,x,tmp,dd;
            v0.set(v,1);
            aa.set(a,1);
            tmp.set(1,2);
            x=v0*t+tmp*aa*t*t;
            dd.set(d,1);
            x=x+dd;
            ll fox=sldiv(x.a,x.b);
            if (fox>l)fox=l;
            for (ll j=d;j<=fox;j++){
                if (vis[j]){
                    cnt[j]++;
                    break;
                }
            }
        }else{
            if (v>vmax){
                int pos=find(v,n);
                if (vis[pos])cnt[p[pos]]++;
                continue;
            }
            Frac t;
            t.set(vmax-v,a);
            Frac v0,aa,x,tmp,dd;
            v0.set(v,1);
            aa.set(a,1);
            tmp.set(1,2);
            x=v0*t+tmp*aa*t*t;
            dd.set(d,1);
            x=x+dd;
            ll fox=sldiv(x.a,x.b);
            if (fox>l)fox=l;
            for (ll j=d;j<=fox;j++){
                if (vis[j]){
                    cnt[j]++;
                    break;
                }
            }
        }
    }
    for (int i=1;i<=N;i++){
        if (vis[i])osn+=cnt[i];
        if (vis[i]&&cnt[i]==0)rmv++;
    }
    cout<<osn<<" "<<rmv<<"\n";
}
int main(){
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int _;cin>>_;
    while(_--)solve();
    return 0;
}